#include "hal_softiic.h"
#include "main.h"
//SDA的IO方向(输入/输出)
//#define SoftI2CSdaIn()	{GPIOC->CRL&=0X0FFFFFFF;GPIOC->CRL|=(uint32_t)8<<28;}
//#define SoftI2CSdaOut()	{GPIOC->CRL&=0X0FFFFFFF;GPIOC->CRL|=(uint32_t)3<<28;}
//设置高低电平
#define SetSoftI2CSDA() HAL_GPIO_WritePin(IIC_AIR_PRE_SDA_GPIO_Port, IIC_AIR_PRE_SDA_Pin, GPIO_PIN_SET)
#define ClrSoftI2CSDA() HAL_GPIO_WritePin(IIC_AIR_PRE_SDA_GPIO_Port, IIC_AIR_PRE_SDA_Pin, GPIO_PIN_RESET)
#define SetSoftI2CSCL() HAL_GPIO_WritePin(IIC_AIR_PRE_SCL_GPIO_Port, IIC_AIR_PRE_SCL_Pin, GPIO_PIN_SET)
#define ClrSoftI2CSCL() HAL_GPIO_WritePin(IIC_AIR_PRE_SCL_GPIO_Port, IIC_AIR_PRE_SCL_Pin, GPIO_PIN_RESET)
//读取高低电平
#define SoftI2C_SDA_H() (HAL_GPIO_ReadPin(IIC_AIR_PRE_SDA_GPIO_Port, IIC_AIR_PRE_SDA_Pin) == GPIO_PIN_SET)
#define SoftI2C_SDA_L() (HAL_GPIO_ReadPin(IIC_AIR_PRE_SDA_GPIO_Port, IIC_AIR_PRE_SDA_Pin) == GPIO_PIN_RESET)
#define SoftI2C_SCL_H() (HAL_GPIO_ReadPin(IIC_AIR_PRE_SCL_GPIO_Port, IIC_AIR_PRE_SCL_Pin) == GPIO_PIN_SET)

//#define IIC_SCK_Pin GPIO_PIN_6
//#define IIC_SCK_GPIO_Port GPIOB
//#define IIC_SDA_Pin GPIO_PIN_7
//#define IIC_SDA_GPIO_Port GPIOB
//#define IIC_AIR_PRE_SCL_Pin 										GPIO_PIN_6    //气压计
//#define IIC_AIR_PRE_SCL_GPIO_Port 							GPIOB
//	
//#define IIC_AIR_PRE_SDA_Pin 										GPIO_PIN_7
//#define IIC_AIR_PRE_SDA_GPIO_Port 							GPIOB


void SoftI2CSdaIn(void)
{
//	uint32_t ioTemp;

//	ioTemp = IIC_AIR_PRE_SDA_GPIO_Port->CRL;
//	ioTemp &= 0X0FFFFFFF;
//	ioTemp |= 0X80000000;
//	IIC_AIR_PRE_SDA_GPIO_Port->CRL = ioTemp;
	gpio_init(IIC_AIR_PRE_SDA_GPIO_Port, 					GPIO_MODE_IPU, 			GPIO_OSPEED_50MHZ,	IIC_AIR_PRE_SDA_Pin);//气压计
	SetSoftI2CSDA();
}

void SoftI2CSdaOut(void)
{
  gpio_init(IIC_AIR_PRE_SDA_GPIO_Port, 					GPIO_MODE_OUT_PP, 	GPIO_OSPEED_50MHZ,	IIC_AIR_PRE_SDA_Pin);//气压计
//	uint32_t ioTemp;
  
//	ioTemp = IIC_SDA_GPIO_Port->CRL;
//	ioTemp &= 0X0FFFFFFF;
//	ioTemp |= 0X30000000;
//	IIC_SDA_GPIO_Port->CRL = ioTemp;
}
/**
 * 用于模拟IIC时的简单微秒级延时
 */
void delay_us(uint8_t ms)
{
	uint8_t i;
	while(ms--)
	{
		for(i=16*2;i>0;i--)
        {
					;;
        }
	}
}

/**
 *iic启动:当SCL处于高电平状态时，SDA出现一个下降沿,即产生IIC启动信号
 */
void iic_start(void) {
	SoftI2CSdaOut();
	SetSoftI2CSDA();
	SetSoftI2CSCL();
	delay_us(5);
	ClrSoftI2CSDA();
	delay_us(5);
	ClrSoftI2CSCL();
}

/**
 *iic停止:当SCL处于高电平状态时，SDA出现一个上升沿,即产生IIC停止信号
 */
void iic_stop(void) {
	SoftI2CSdaOut();
	ClrSoftI2CSCL();
	ClrSoftI2CSDA();
	delay_us(5);
	SetSoftI2CSCL();
	SetSoftI2CSDA();
	delay_us(5);
}

/**
 *IIC等待应答信号
 *ack_status： 应答状态，0表示应答，1表示设备无响应
 */
uint8_t iic_wait_ack(void) {
	uint8_t err_time = 0;
	SoftI2CSdaIn();
	SetSoftI2CSDA();
	delay_us(1);
	SetSoftI2CSCL();
	delay_us(1);
	while (SoftI2C_SDA_H()) {
		err_time++;
		if (err_time > 250) {
		//	iic_stop();
			return 1;
		}
	}
	ClrSoftI2CSCL();
	return 0;
}

/**
 *主机（主控制器）产生应答信号
 */
void iic_ack(void) {
	ClrSoftI2CSCL();
	SoftI2CSdaOut();
	ClrSoftI2CSDA();
	delay_us(2);
	SetSoftI2CSCL();
	delay_us(2);
	ClrSoftI2CSCL();
}

/**
 * 主机（主控制器）产生不应答信号
 */
void iic_nack(void) {
	ClrSoftI2CSCL();
	SoftI2CSdaOut();
	SetSoftI2CSDA();
	delay_us(2);
	SetSoftI2CSCL();
	delay_us(2);
	ClrSoftI2CSCL();
}

/**
 *IIC发送1byte数据
**/
void iic_sendbyte(uint8_t byte) {
	uint8_t i;
	SoftI2CSdaOut();
	ClrSoftI2CSCL();
	/** 发送一个字节的高7位 */
	for (i = 0; i < 8; i++) {
		if (byte & 0x80) {
			SetSoftI2CSDA();
		} else {
			ClrSoftI2CSDA();
		}
		byte <<= 1;
		delay_us(2);
		SetSoftI2CSCL();
		delay_us(2);
		ClrSoftI2CSCL();
		delay_us(5);
	}
}

/**
 *IIC读取1byte数据
 */
uint8_t iic_readbyte(uint8_t ack) {
	uint8_t i;
	uint8_t recv_value = 0;
	SoftI2CSdaIn();
	for (i = 0; i < 8; i++) {
		ClrSoftI2CSCL();
		delay_us(2);
		SetSoftI2CSCL();
		recv_value <<= 1;
		if (SoftI2C_SDA_H()) {
			recv_value++;
		}
	}
	if(!ack){
		iic_nack();
	}
	else{
		iic_ack();
	}


	return recv_value;
}
